package com.sq.imp.MyMenuManagers;

import com.sq.abstractClass.Text;
import org.pushingpixels.substance.api.SubstanceCortex;
import org.pushingpixels.substance.api.SubstanceSkin;
import org.pushingpixels.substance.api.skin.*;

import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.undo.UndoManager;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class EditManager {
    private final Text textArea;
    private final UndoManager undoManager;
    private final JFrame frame;
    private static final int BYTES_PER_LINE = 16;
    public EditManager(Text textArea, JFrame frame) {
        this.textArea = textArea;
        this.undoManager = new UndoManager();
        textArea.getDocument().addUndoableEditListener(undoManager);
        this.frame = frame;
    }

    public void copy() {
        textArea.copy();
    }

    public void paste() {
        textArea.paste();
    }

    public void cut() {
        textArea.cut();
    }

    public void undo() {
        if (undoManager.canUndo()) {
            undoManager.undo();
        } else {
            JOptionPane.showMessageDialog(frame, "没有可撤回的操作", "提示", JOptionPane.INFORMATION_MESSAGE);
        }
    }

    public void redo() {
        if (undoManager.canRedo()) {
            undoManager.redo();
        } else {
            JOptionPane.showMessageDialog(frame, "没有可重做的操作", "提示", JOptionPane.INFORMATION_MESSAGE);
        }
    }

    // 显示十六进制编辑器窗口
    public void showHexEditor(JFrame parent, String text) {
        JFrame hexFrame = new JFrame("十六进制编辑器");
        hexFrame.setSize(1000, 700);
        hexFrame.setLocationRelativeTo(parent);

        // 编码选择下拉框
        String[] availableEncodings = {
                "UTF-8", "GBK", "GB2312", "ISO-8859-1", "UTF-16", "UTF-16BE", "UTF-16LE"
        };

        if (textArea.getEncoding() != null && !textArea.getEncoding().isEmpty()) {
            int signal = 1;
            for (String encoding : availableEncodings) {
                if (textArea.getEncoding().equals(encoding)) {
                    signal = 0;
                    break;
                }
            }
            if (signal == 1) {
                availableEncodings = Arrays.copyOf(availableEncodings, availableEncodings.length + 1);
                availableEncodings[availableEncodings.length - 1] = textArea.getEncoding();
            }
        }
        JComboBox<String> encodingComboBox = new JComboBox<>(availableEncodings);
        encodingComboBox.setSelectedItem(textArea.getEncoding() != null && !textArea.getEncoding().isEmpty() ? textArea.getEncoding() : "UTF-8" );

        // 十六进制文本区域（不可编辑，格式固定）
        JTextArea hexTextArea = new JTextArea(30, 80);
        hexTextArea.setEditable(false);
        JScrollPane hexScrollPane = new JScrollPane(hexTextArea);

        // 原始文本预览区域（可编辑）
        JTextArea previewTextArea = new JTextArea(10, 80);
        previewTextArea.setBorder(BorderFactory.createTitledBorder("文本预览"));
        JScrollPane previewScrollPane = new JScrollPane(previewTextArea);

        // 按钮面板
        JPanel buttonPanel = new JPanel();
        JButton applyButton = new JButton("应用编码");
        JButton updateButton = new JButton("更新十六进制");
        JButton copyButton = new JButton("复制十六进制");
        JButton pasteButton = new JButton("粘贴到原文");
        JButton resetButton = new JButton("重置到最初内容");

        // 初始显示
        updateHexView(text, (String)encodingComboBox.getSelectedItem(), hexTextArea, previewTextArea);

        // 应用编码按钮事件
        applyButton.addActionListener(e -> {
            String encoding = (String) encodingComboBox.getSelectedItem();
            updateHexView(previewTextArea.getText(), encoding, hexTextArea, previewTextArea);
        });

        // 更新十六进制按钮事件
        updateButton.addActionListener(e -> {
            String encoding = (String) encodingComboBox.getSelectedItem();
            try {
                String newText = previewTextArea.getText();
                updateHexView(newText, encoding, hexTextArea, previewTextArea);
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(
                        hexFrame,
                        "更新失败: " + ex.getMessage(),
                        "错误",
                        JOptionPane.ERROR_MESSAGE
                );
            }
        });

        // 复制十六进制按钮事件
        copyButton.addActionListener(e -> {
            hexTextArea.selectAll();
            hexTextArea.copy();
            hexTextArea.setCaretPosition(0);
        });

        // 粘贴到原文按钮事件
        pasteButton.addActionListener(e -> {
            String hexText = hexTextArea.getText();
            try {
                String encoding = (String) encodingComboBox.getSelectedItem();
                String temp = hexToText(hexText, encoding);
                previewTextArea.setText(temp);
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(
                        hexFrame,
                        "转换失败: " + ex.getMessage(),
                        "错误",
                        JOptionPane.ERROR_MESSAGE
                );
            }
        });
        String[] initialState = new String[] { text, "UTF-8" };
        // 重置到最初内容按钮事件
        resetButton.addActionListener(e -> {
            String initialText = initialState[0];
            String initialEncoding = initialState[1];

            encodingComboBox.setSelectedItem(initialEncoding);
            previewTextArea.setText(initialText);
            updateHexView(initialText, initialEncoding, hexTextArea, previewTextArea);
        });

        // 添加按钮到面板
        buttonPanel.add(encodingComboBox);
        buttonPanel.add(applyButton);
        buttonPanel.add(updateButton);
        buttonPanel.add(copyButton);
        buttonPanel.add(pasteButton);
        buttonPanel.add(resetButton);

        // 组装窗口内容
        JSplitPane splitPane = new JSplitPane(
                JSplitPane.VERTICAL_SPLIT,
                hexScrollPane,
                previewScrollPane
        );
        splitPane.setDividerLocation(450);

        hexFrame.setLayout(new BorderLayout());
        hexFrame.add(buttonPanel, BorderLayout.NORTH);
        hexFrame.add(splitPane, BorderLayout.CENTER);

        hexFrame.setVisible(true);
    }

    // 更新十六进制视图
    private static void updateHexView(String text, String encoding,
                                      JTextArea hexTextArea, JTextArea previewTextArea) {
        try {
            byte[] bytes = text.getBytes(encoding);
            String hexView = bytesToHexView(bytes);
            hexTextArea.setText(hexView);

            // 更新预览文本（确保显示正确）
            String previewText = new String(bytes, encoding);
            previewTextArea.setText(previewText);
        } catch (Exception e) {
            hexTextArea.setText("转换失败: " + e.getMessage());
        }
    }

    // 将字节数组转换为十六进制视图
    private static String bytesToHexView(byte[] bytes) {
        StringBuilder hexBuilder = new StringBuilder();
        int offset = 0;

        for (int i = 0; i < bytes.length; i += BYTES_PER_LINE) {
            // 添加偏移量
            hexBuilder.append(String.format("%08X: ", offset));
            offset += BYTES_PER_LINE;

            // 十六进制表示
            StringBuilder hexLine = new StringBuilder();
            // 字符表示
            StringBuilder charLine = new StringBuilder();

            // 处理每行的字节
            for (int j = 0; j < BYTES_PER_LINE; j++) {
                if (i + j < bytes.length) {
                    byte b = bytes[i + j];
                    // 添加十六进制表示
                    hexLine.append(String.format("%02X ", b));
                    // 添加字符表示（可打印字符）
                    if (b >= 32 && b <= 126) {
                        charLine.append((char) b);
                    } else {
                        charLine.append('.');
                    }
                } else {
                    // 填充空格
                    hexLine.append("   ");
                    charLine.append(' ');
                }
            }

            // 添加到结果
            hexBuilder.append(hexLine).append(" | ").append(charLine).append("\n");
        }

        return hexBuilder.toString();
    }

    // 将十六进制视图转换回文本
    private static String hexToText(String hexView, String encoding) throws Exception {
        List<Byte> byteList = new ArrayList<>();

        // 逐行解析
        String[] lines = hexView.split("\n");
        for (String line : lines) {
            if (line.trim().isEmpty()) continue;

            // 找到第一个冒号，跳过偏移量
            int colonIndex = line.indexOf(':');
            if (colonIndex < 0) continue;

            String hexPart = line.substring(colonIndex + 1);

            // 找到竖线，只处理竖线前面的十六进制部分
            int pipeIndex = hexPart.indexOf('|');
            if (pipeIndex < 0) continue;

            hexPart = hexPart.substring(0, pipeIndex).trim();

            // 分割十六进制值
            String[] hexValues = hexPart.split("\\s+");
            for (String hex : hexValues) {
                if (hex.isEmpty()) continue;
                try {
                    byte b = (byte) Integer.parseInt(hex, 16);
                    byteList.add(b);
                } catch (NumberFormatException e) {
                    // 忽略非十六进制字符
                }
            }
        }

        // 转换为字节数组
        byte[] bytes = new byte[byteList.size()];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = byteList.get(i);
        }

        // 使用指定编码转换为字符串
        return new String(bytes, encoding);
    }

    public void createSkinMenuItems(JMenu menu) {

        // 皮肤列表
        final Class<?>[] SKINS = {
                BusinessSkin.class,
                BusinessBlueSteelSkin.class,
                BusinessBlackSteelSkin.class,
                CremeSkin.class,
                CremeCoffeeSkin.class,
                DustSkin.class,
                GraphiteSkin.class,
                MagellanSkin.class,
                RavenSkin.class,
                SaharaSkin.class,
                AutumnSkin.class,
                TwilightSkin.class
        };

        // 皮肤描述
        final String[] SKIN_DESCRIPTIONS = {
                "简约商务风格，采用柔和蓝色调与中性配色，适合企业级应用和办公软件",
                "深蓝钢色变体，增强了金属质感与专业度，提供冷静高效的视觉体验",
                "黑色商务主题，搭配金色或银色点缀，适合高端财务、数据分析类应用",
                "柔和米色/奶油色基调，低对比度设计，提供舒适阅读体验的文档类应用",
                "温暖咖啡色调变体，结合米色背景与深棕元素，营造温馨专业的氛围",
                "模拟Windows Vista Aero效果，大米与石墨相间，提供现代桌面应用外观",
                "macOS风格深色主题，采用石墨灰与银色元素，适合创意设计类软件",
                "高对比度黑白主题，优化文本可读性，适合长时间阅读的文档处理工具",
                "全黑色调主题，搭配明亮强调色，适合需要高视觉冲击力的专业工具",
                "黄色/橙色高对比度主题，专为视力障碍用户优化，确保界面清晰可辨",
                "秋季色彩主题，采用橙红色渐变与金色点缀，适合季节性或创意应用",
                "深紫色与黑色渐变主题，提供现代感与科技感，适合高端演示类软件"
        };

        ButtonGroup skinGroup = new ButtonGroup();

        for (int i = 0; i < SKINS.length; i++) {
            Class<?> skinClass = SKINS[i];
            JRadioButtonMenuItem item = new JRadioButtonMenuItem(
                    skinClass.getSimpleName().replace("Skin", ""));

            // 设置菜单项的工具提示
            item.setToolTipText(SKIN_DESCRIPTIONS[i]);

            // 默认选中BusinessSkin
            if (skinClass == BusinessSkin.class) {
                item.setSelected(true);
            }

            item.addActionListener(new SkinChangeListener(skinClass));
            menu.add(item);
            skinGroup.add(item);

            if (skinClass == DustSkin.class)
                menu.addSeparator();
        }
    }

    private class SkinChangeListener implements ActionListener {
        private Class<?> skinClass;

        public SkinChangeListener(Class<?> skinClass) {
            this.skinClass = skinClass;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            SwingUtilities.invokeLater(() -> {
                try {
                    // 使用反射创建皮肤实例
                    SubstanceSkin skin = (SubstanceSkin) skinClass.getDeclaredConstructor().newInstance();
                    SubstanceCortex.GlobalScope.setSkin(skin);

                    // 更新窗口标题显示当前皮肤
                    frame.setTitle(frame.getTitle().split("-")[0] + "-当前皮肤: " +
                            skinClass.getSimpleName().replace("Skin", ""));

                    // 重绘窗口以应用新皮肤
                    frame.repaint();

                } catch (Exception ex) {
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(
                            frame,
                            "无法应用皮肤: " + ex.getMessage(),
                            "皮肤更改失败",
                            JOptionPane.ERROR_MESSAGE
                    );
                }
            });
        }
    }
}
